import re
import json
from django.shortcuts import render, redirect, HttpResponse
from configCenter import models
from user_system import models as user_models
from utils.auth_manog import auth_manog_done
from utils import pagination
from configCT.settings import logger
from django.db.models import Q
from django.http import JsonResponse
from utils.get_current_token import get_token
from utils.hashlib_done import encryption
from utils.create_game_config import create_game_config


@auth_manog_done
def gameserver_list(request):
    project_id = request.session.get("project_id")
    if not project_id:
        return HttpResponse("没有选择项目，不可操作")
    select_group_name = "选择分区"
    gameserver_group_id_filter = ""
    gameserver_group_list = models.GameServerGroup.objects.filter(b_project_id=project_id).all().order_by("group_name")

    gameserver_filter = ""
    game_list = []

    if request.method == "GET":
        gameserver_group_id = request.GET.get("gameserver_group_id_filter", "")
        gameserver_filter = request.GET.get("gameserver_filter", "")
        filter_son_gameserver = request.GET.get("filter_son_gameserver", "")
        if gameserver_group_id and filter_son_gameserver:
            gameserver_group_id = gameserver_group_id.strip()
            game_list = models.GameServer.objects.filter(b_project_id=project_id, b_group_id=gameserver_group_id,
                                                         is_son=False).order_by("-server_id").all()
        elif gameserver_group_id:
            # print("gameserver_group_id条件成立")
            game_list = models.GameServer.objects.filter(b_project_id=project_id,
                                                         b_group_id=gameserver_group_id).order_by("-server_id").all()
        elif filter_son_gameserver:
            game_list = models.GameServer.objects.filter(b_project_id=project_id, is_son=False).order_by(
                "-server_id").all()
        elif gameserver_filter:
            # print("gameserver_filter条件成立")
            game_list = models.GameServer.objects.filter(b_project_id=project_id).filter(
                Q(server_id__contains=gameserver_filter) |
                Q(server_name__contains=gameserver_filter) |
                Q(server_dir__contains=gameserver_filter) |
                Q(server_ip__contains=gameserver_filter)
            ).order_by("-server_id").all()
        else:
            # print("=============第一次请求页面时 访问这里")
            game_list = models.GameServer.objects.filter(b_project_id=project_id).order_by(
                "-server_id").all()  # 通过项目得到游戏服
    elif request.method == "POST":
        gameserver_group_id = request.POST.get("gameserver_group_id", "")
        gameserver_filter = request.POST.get("gameserver_filter", "")

        if gameserver_group_id:
            gameserver_group_id = gameserver_group_id.strip()
            game_list = models.GameServer.objects.filter(b_project_id=project_id,
                                                         b_group_id=gameserver_group_id).order_by(
                "-server_id").all()
            select_group_name = models.GameServerGroup.objects.filter(b_project_id=project_id,
                                                                      id=gameserver_group_id).first().group_name
            gameserver_group_id_filter = gameserver_group_id
        elif gameserver_filter:
            gameserver_filter = gameserver_filter.strip()
            game_list = models.GameServer.objects.filter(b_project_id=project_id).filter(
                Q(server_id__contains=gameserver_filter) |
                Q(server_name__contains=gameserver_filter) |
                Q(server_dir__contains=gameserver_filter) |
                Q(server_ip__contains=gameserver_filter)
            ).order_by("-server_id")
        else:
            game_list = models.GameServer.objects.filter(b_project_id=project_id).order_by(
                "-server_id").all()  # 通过项目得到游戏服

    game_number = game_list.count()
    current_page = int(request.GET.get("Page", 1))  # 获取用户get请求的页码数
    select_current_page = int(request.COOKIES.get("per_page_count", 30))  # 获取当前页面cookie记录的显示条数,默认是10
    page_obj = pagination.Page(gameserver_group_id, gameserver_filter, current_page, len(game_list),
                               select_current_page)  # 创建page_obj对象  per_page_count=10,page_num=7是变量，可改动
    game_list = game_list[page_obj.start_count:page_obj.end_count]  # 每页显示数据条数列表
    page_list = page_obj.page_str("")  # 分页的所有内容

    auth_type_list = user_models.MyAuthType.objects.all()
    cross_server_list = models.GameServer.objects.filter(b_project_id=project_id, cross_status="True").all().order_by(
        "server_id")

    return render(request, "super_cmdb/gameserver_list.html", {
        "game_list": game_list,
        "page_list": page_list,
        "game_number": game_number,
        "project_id": project_id,
        "auth_type_list": auth_type_list,
        "gameserver_group_list": gameserver_group_list,
        "select_group_name": select_group_name,
        "gameserver_group_id_filter": gameserver_group_id_filter,
        "gameserver_filter": gameserver_filter,
        "cross_server_list": cross_server_list
    })

@auth_manog_done
def install_game_new(request):
    project_id = request.session.get("project_id")

    if request.method == "GET":
        auth_type_list = user_models.MyAuthType.objects.all()
        gameserver_group_list = models.GameServerGroup.objects.filter(b_project_id=project_id).all().order_by(
            "group_name")
        conf_template_list = models.ConfSettingCenter.objects.filter(b_project_id=project_id, purpose=1).all()

        return render(request, "super_cmdb/install_game_new.html", {
            "project_id": project_id,
            "auth_type_list": auth_type_list,
            "gameserver_group_list": gameserver_group_list,
            "conf_template_list": conf_template_list,
        })
    elif request.method == "POST":
        try:
            server_dir = request.POST.get("server_dir")
            start_server_dir = server_dir.strip()
            start_server_id = int(request.POST.get("server_id"))
            group_id = request.POST.get("group_id")
            version = request.POST.get("version")
            start_server_name = request.POST.get("server_name")
            template_id = request.POST.get("template_id")
            install_number = int(request.POST.get("install_number"))

            faild_list = []
            for number in range(install_number):
                # 随机从可用机器列表中抽取一台机器
                server_ip = "127.0.0.1"
                host_port = 22
                # 获取当前机器已装服数，包括子服，不然可能会冲突
                # 这个算法也有点问题，合服后端口会一直增大，但是单台机器装服会超过300个吗？？？留个bug
                max_gameserver_obj = models.GameServer.objects.filter(server_ip=server_ip).all().order_by("-id").first()
                if max_gameserver_obj:
                    curr_max_config_content = max_gameserver_obj.config_content
                    curr_max_config_json = json.loads(curr_max_config_content)
                    curr_max_ranking = curr_max_config_json["yunwei_config"]["ranking"]
                    # 新服处于第几个服
                    ranking = curr_max_ranking + 1
                else:
                    # 新服处于第几个服
                    ranking = 1
                # 计算新服端口号需要累加的数量
                append_number = ranking * 3

                template_obj = models.ConfSettingCenter.objects.filter(id=template_id).first()
                template_json = json.loads(template_obj.setting_content)

                # 组合服务器信息
                server_id = start_server_id + number
                server_dir = start_server_dir + str(server_id) + "a"
                server_name = start_server_name + str(server_id) + "服"

                template_json["yunwei_config"] = {}
                template_json["yunwei_config"]["server_dir"] = server_dir
                template_json["yunwei_config"]["server_id"] = server_id
                template_json["yunwei_config"]["server_ip"] = server_ip
                template_json["yunwei_config"]["ranking"] = ranking
                template_json["yunwei_config"]["install_version"] = version
                # 固定的端口用大写的PORT
                template_json["yunwei_config"]["host_PORT"] = host_port

                # 获取域名
                DOMAIN = None

                # 配置文件处理替换变量，配置端口
                config_content = create_game_config(models, template_json, append_number, server_id, DOMAIN, project_id)

                # 将游戏服信息写进服务器列表
                if not models.GameServer.objects.filter(b_project_id=project_id, server_id=server_id).first():
                    models.GameServer.objects.create(server_name=server_name, server_id=server_id, server_ip=server_ip,
                                                     server_dir=server_dir, ssh_port=host_port, b_project_id=project_id,
                                                     b_group_id=group_id, timing_task_status=1,
                                                     config_content=config_content,
                                                     deploy_status=1, b_template_id=template_id)

                else:
                    faild_list.append(server_id)
            if faild_list:
                message = {"code": 0, "msg": "配置已生成，其中配置失败的应用: %s, 已存在，请更换server_id" % faild_list}
            else:
                message = {"code": 0, "msg": "配置已生成，可继续配置新应用"}
        except Exception as e:
            logger.error(e)
            logger.error(
                '异常文件：%s ,异常行号：%s' % (e.__traceback__.tb_frame.f_globals['__file__'], e.__traceback__.tb_lineno))
            message = {"code": 1, "msg": "应用配置任务异常,ERR: %s" % e}
        return JsonResponse(message, json_dumps_params={"ensure_ascii": False, "sort_keys": True, "indent": 4})

@auth_manog_done
def gameserver_config_detail(request, server_id):
    """
    查看游戏服的配置信息
    :param request:
    :param server_id:
    :return:
    """
    project_id = request.session.get("project_id")
    if request.method == "GET":
        gameserver_obj = models.GameServer.objects.filter(b_project_id=project_id, server_id=server_id).first()
        config_content = gameserver_obj.config_content
        return render(request, "super_cmdb/gameserver_config_detail.html", {"config_content": config_content})

@auth_manog_done
def gameserver_edit(request, id):
    """
    编辑游戏服
    :param request:
    :return:
    """
    project_id = request.session.get("project_id")
    if request.method == 'GET':
        gameserver_info = models.GameServer.objects.filter(b_project_id=project_id, id=id).first()
        b_group_list = models.GameServerGroup.objects.filter(b_project_id=project_id).all().order_by("group_name")
        b_group_id = gameserver_info.b_group_id
        current_id_group_info = models.GameServerGroup.objects.filter(b_project_id=project_id, id=b_group_id).first()
        return render(request, "super_cmdb/gameserver_edit.html",
                      {"gameserver_info": gameserver_info, "b_group_list": b_group_list,
                       "current_id_group_info": current_id_group_info})
    if request.method == "POST":
        server_name = request.POST.get("server_name", None)
        server_dir = request.POST.get("server_dir", None)
        server_ip = request.POST.get("server_ip", None)
        b_group_id = request.POST.get("b_group_id", None)
        if server_name and server_dir and server_ip and b_group_id:
            try:
                gameserver_obj = models.GameServer.objects.filter(b_project_id=project_id, id=id).first()
                server_id = gameserver_obj.server_id
                config_content = gameserver_obj.config_content
                config_content_json = json.loads(config_content)
                if "yunwei_config" not in config_content_json.keys(): config_content_json["yunwei_config"] = {}
                config_content_json["yunwei_config"]["server_id"] = server_id
                config_content_json["yunwei_config"]["server_dir"] = server_dir
                config_content_json["yunwei_config"]["server_ip"] = server_ip
                config_content = json.dumps(config_content_json, ensure_ascii=False, sort_keys=True, indent=4)
                models.GameServer.objects.filter(b_project_id=project_id, id=id).update(
                    server_name=server_name,
                    server_dir=server_dir,
                    server_ip=server_ip,
                    b_group_id=b_group_id,
                    config_content=config_content
                )
                message = {"code": 0, "msg": "修改成功"}
            except Exception as e:
                error_info = '异常：%s ,异常文件：%s ,异常行号：%s' % (
                    e, e.__traceback__.tb_frame.f_globals['__file__'], e.__traceback__.tb_lineno)
                logger.error(error_info)
                message = {"code": 1, "msg": error_info}
        else:
            message = {"code": 1, "msg": "关键信息不全，修改失败"}
        return JsonResponse(message)

@auth_manog_done
def gameserver_del(request):
    ops_username = request.session.get("username")
    project_id = request.session.get("project_id")
    if request.method == "POST":
        gameserver_id = request.POST.get("gameserver_id")  # 前端传过来的全是字符串
        print(gameserver_id)
        nums = re.findall(r'\d+', gameserver_id)  # 匹配gameserver_id组成数组
        print(nums)
        if isinstance(nums, list):  # 判断gameserver_id是不是一个list
            for id in nums:
                # id = int(id)
                print(id)
                server_name = models.GameServer.objects.filter(b_project_id=project_id,
                                                               server_id=id).first().server_name
                models.GameServer.objects.filter(b_project_id=project_id, server_id=id).delete()
                log_success = "项目id: %s 删除游戏服【%s】成功" % (project_id, server_name)
                user_models.OpsLogger.objects.create(log_user=ops_username, log_ops=log_success)
                print(log_success)
        return redirect("/super_cmdb/gameserver_list/")

def gameserver_config_api(request):
    """
    通过api获取游戏服配置信息
    :param request:
    :return: json message
    """
    if request.method == "GET":
        current_token = get_token()
        token = request.GET.get("token", None)
        if token:
            token = encryption(token)
        project_id = request.GET.get("project_id", None)
        server_id = request.GET.get("server_id", None)
        if token == current_token:
            if project_id and server_id:
                try:
                    gameserver_obj = models.GameServer.objects.filter(b_project_id=project_id,
                                                                      server_id=server_id).first()
                    config_str = gameserver_obj.config_content
                    config_dict = json.loads(config_str)
                except Exception as e:
                    logger.error(e)
                    logger.error('异常文件：%s ,异常行号：%s' % (
                        e.__traceback__.tb_frame.f_globals['__file__'], e.__traceback__.tb_lineno))
                    config_dict = {"code": 1, "msg": "获取游戏服配置失败,ERR: %s" % e}
        else:
            config_dict = {"code": 1, "msg": "认证失败"}
        return JsonResponse(config_dict, json_dumps_params={"ensure_ascii": False, "sort_keys": True, "indent": 4})

